package assignment1;

//
/**
 *
 * @author rain.divine88
 */

import java.util.ArrayList;
import java.util.Random;

public class UIClass {
    
    private char[][] gridUI;
    private getSetClass gsClass;
    private int gridSize;

    private static final int FIRST_LANE_BOUNDARY = 12;
    private static final int SECOND_LANE_BOUNDARY = 12;
    private int startSimulation = 0;

    //variables for traffic light change cycle
    private static final int FIRST_TRAFFIC_LIGHT = 2;
    private static final int SECOND_TRAFFIC_LIGHT = 5;
    private static final int THIRD_TRAFFIC_LIGHT = 8;

    //variables for traffic location
    private static final int LIGHT_LOCK = 12;
    private static final int H_LIGHT_LOCK = 11;
    private static final int V_LIGHT_LOCK = 17;

    //array lists for vertical cars and horizontal cars
    private ArrayList<CarObj> vCarsArray;
    private ArrayList<CarObj> hCarsArray;    

    public UIClass(getSetClass gsClass){
        this.gsClass = gsClass;
        gridUI = new char[gsClass.getGridSize()][gsClass.getGridSize()];
        gridSize = gsClass.getGridSize();
        vCarsArray = new ArrayList<CarObj>();
        hCarsArray = new ArrayList<CarObj>();      
    }

    //method for setting up grid and setting up lanes and traffic lights
    public void roughGrid(char c){
        for (int row = 0; row < gridSize; row++) {
            for (int col = 0; col < gridSize; col++) {
                gridUI[row][col] = c;
            }
        }
        setupHLane();
        setupVLane();
        setupHTrafficLight();
        setupVTrafficLight();
    }

    //method for printing out the grid on form
    public void showGrid(){
        for (int row = 0; row  < gridSize; row ++) {
            for (int col = 0; col  < gridSize; col ++) {
                System.out.print(gridUI[row][col]);
            }
            System.out.println(" ");
        }
    }

    public void showGridOnForm(){        
        setupHTrafficLight();
        setupVTrafficLight();
        setupCars();
        showGrid();
    }

    //setting up vertical lanes and putting values into array
    private void setupVLane(){
        int midGrid = gridSize / 2;
        int verLane = gsClass.getVLaneNumber();

        for (int row = 0; row  < gridSize; row ++) {
            for (int col = 0; col  < verLane; col ++) {
                gridUI[row][midGrid + col] = '|';
            }
        }
    }

    //setting up horizontal lanes and putting values into array
    private void setupHLane(){
        int midGrid = gridSize / 2;
        int horLane = gsClass.getHLaneNumber();

        for (int row = 0; row  < gridSize; row ++) {
            for (int col = 0; col  < horLane; col ++) {
                gridUI[midGrid + col][row] = '-';
            }
        }
    }    

    //setting up horizontal traffic light
    public void setupHTrafficLight(){
        if (gsClass.getHLaneTrafficLight() == true) {
            gridUI[LIGHT_LOCK][H_LIGHT_LOCK] = 'G';
        } else if (gsClass.getHLaneTrafficLight() == false){
            gridUI[LIGHT_LOCK][H_LIGHT_LOCK] = 'R';
        }
    }

    //setting up vertical traffic light
    public void setupVTrafficLight(){
        if (gsClass.getVLaneTrafficLight() == true) {
            gridUI[LIGHT_LOCK][V_LIGHT_LOCK] = 'G';
        }else if (gsClass.getVLaneTrafficLight() == false) {
            gridUI[LIGHT_LOCK][V_LIGHT_LOCK] = 'R';
        }
    }

    //setting up all horizontal and vertical cars
    private void setupCars(){
        //putting horizontal cars into array
        for (int i = 0; i < hCarsArray.size(); i++) {
            CarObj myCar = hCarsArray.get(i);
            gridUI[myCar.getRow()][myCar.getCol()] = 'c';
        }
        //putting vertical cars into array
        for (int i = 0; i < vCarsArray.size(); i++) {
            CarObj myCar = vCarsArray.get(i);
            gridUI[myCar.getRow()][myCar.getCol()] = 'c';
        }
    }

    //adding horizontal cars into car array object
    private void addHLaneCars(){        
        for (int row = 1; row  <= gsClass.getHLaneNumber(); row ++) {
            Random rand = new Random();
            float randNum = rand.nextFloat();
            if (randNum <= gsClass.getProbHLane()) {
                hCarsArray.add(new CarObj(FIRST_LANE_BOUNDARY + row, 0));
            }
            moveHLaneCars();
        }
    }

    //adding vertical cars into car array object
    private void addVLaneCars(){        
        for (int col = 1; col  <= gsClass.getVLaneNumber(); col ++) {
            Random rand = new Random();
            float randNum = rand.nextFloat();
            if (randNum <= gsClass.getProbVLane()) {
                vCarsArray.add(new CarObj(0, SECOND_LANE_BOUNDARY + col));
            }
            moveVLaneCars();
        }
    }

    public void addAllCars(){        
        addHLaneCars();
        addVLaneCars();
        showGridOnForm();
    }

    //moving cars
    public  void moveCars(int numSimulation){        
         for (startSimulation = 1; startSimulation <= numSimulation; startSimulation++) {
             if (startSimulation > numSimulation) {
                 startSimulation = 1;
             }

             //changing traffic light during simulation cycles
             if (startSimulation <= numSimulation) {
                 gsClass.setHLaneTrafficLight(false);
                 gsClass.setVLaneTrafficLight(true);
                 if (startSimulation <= THIRD_TRAFFIC_LIGHT) {
                     gsClass.setHLaneTrafficLight(true);
                     gsClass.setVLaneTrafficLight(false);
                     if (startSimulation <= SECOND_TRAFFIC_LIGHT) {
                         gsClass.setHLaneTrafficLight(false);
                         gsClass.setVLaneTrafficLight(true);
                         if (startSimulation <= FIRST_TRAFFIC_LIGHT) {
                             gsClass.setHLaneTrafficLight(true);
                             gsClass.setVLaneTrafficLight(false);
                         }
                     }
                 }                 
             }
             addAllCars();
             System.out.println(" ");
         }
    }

    //moving horizontal lane cars
    private void moveHLaneCars(){
         for (int car = 0; car  < hCarsArray.size(); car ++) {
             CarObj myCar = hCarsArray.get(car);             
             int col = myCar.getCol();

             //moving horizontal lane cars until traffic light
             if (col != LIGHT_LOCK) {
                 myCar.setCol(col += 1);                 
             }else{
                 //moving horizontal lane cars if traffic light is green
                 if (gsClass.getHLaneTrafficLight() == true) {
                     myCar.setCol(col += 1);
                 }
             }

             //removing cars when they reach end of grid
             if (col > gsClass.getGridSize() - 1) {
                 hCarsArray.remove(myCar);
             }
         }
     }

    //moving vertical lane cars
    private void moveVLaneCars(){
         for (int car= 0; car < vCarsArray.size(); car++) {
             CarObj myCar = vCarsArray.get(car);
             int row = myCar.getRow();             

             //moving vertical lane cars until traffic light
             if (row != LIGHT_LOCK) {
                 myCar.setRow(row += 1);                
             }else{
                 //moving vertical lane cars if traffic light is green
                 if (gsClass.getVLaneTrafficLight() == true) {
                     myCar.setRow(row += 1);                    
                 }
             }

             //removing cars when they reach end of grid
             if (row > gsClass.getGridSize() - 1) {
                 vCarsArray.remove(myCar);
             }
         }
     }
}
